package com.gitee.beiding.timer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.SimpleType;

public class Task {

    private String id;

    //任务名称
    private String name;

    //负载
    private String payloadJson;

    //任务执行时间
    private long time;

    private Long againDelay;

    Long getAgainDelay() {
        return againDelay;
    }

    void setTime(long time) {
        this.time = time;
    }

    //负载的类型
    private String payloadType;

    private Object payload;

    private boolean cancel;

    private boolean starting;

    synchronized boolean setStarting() {
        if (cancel) {
            return false;
        }
        this.starting = true;
        return true;
    }

    synchronized boolean setCancel() {
        if (starting) {
            return false;
        }
        this.cancel = true;
        return true;
    }

    private static ObjectMapper objectMapper = new ObjectMapper();

    public void again(long delay) {
        this.againDelay = delay;
    }

    Task(String name, long time, Object payload) {
        this.name = name;
        this.time = time;
        this.payload = payload;
    }

    public Task(String id, String payloadType, String payloadJson, long time) {
        this.time = time;
        this.payloadJson = payloadJson;
        this.payloadType = payloadType;
        this.id = id;
        try {
            Class<?> aClass = Class.forName(this.payloadType);
            SimpleType type = SimpleType.constructUnsafe(aClass);
            this.payload = objectMapper.readValue(this.payloadJson, type);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public String getId() {
        return id;
    }

    public boolean setId(String id) {

        //id只能指定一次
        if (this.id == null) {
            this.id = id;
            return true;
        }
        return false;
    }

    //任务执行时间
    public long getTime() {
        return time;
    }

    String getName() {
        return name;
    }

    public Object getPayload() {
        return this.payload;
    }

    private void initJson() {
        try {
            this.payloadJson = objectMapper.writeValueAsString(this.payload);
            this.payloadType = this.payload.getClass().getName();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public String getPayloadJson() {
        if (this.payloadJson == null) {
            initJson();
        }
        return this.payloadJson;
    }

    public String getPayloadType() {
        if (this.payloadType == null) {
            initJson();
        }
        return this.payloadType;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Task) {
            return this.id.equals(((Task) obj).id);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.id.hashCode();
    }

    boolean reset() {
        synchronized (this) {
            if (this.cancel) {
                return false;
            }
        }
        this.starting = false;
        this.againDelay = null;

        return true;
    }

}
